package com.mantru.iotpot;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;

import androidx.appcompat.widget.AppCompatSeekBar;

public class MakeSeekBar extends AppCompatSeekBar {

    private Paint paint = new Paint();//Paint 类在 Android 开发中是用来描述绘制操作的各种属性的类。
    private Rect rect = new Rect();//Rect是一个常用的类，代表了一个矩形区域，定义了该矩形的左边、顶边、右边和底边的位置。它被广泛应用于计算尺寸、位置、边界检测等场景中。
    public MakeSeekBar(Context context) {
        //这是最基本的构造函数，用于在代码中直接创建MakeSeekBar对象时调用。
        super(context);
        init();
    }

    public MakeSeekBar(Context context, AttributeSet attrs) {
        //这个构造函数用于在XML布局文件中定义MakeSeekBar时调用。
        super(context, attrs);
        init();
    }

    public MakeSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        //这个构造函数用于在XML布局文件中定义MakeSeekBar时，同时指定一个默认的样式资源。
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {//一个用于设置画笔属性的方法。
        paint.setColor(Color.WHITE); // 设置画笔颜色为白色
        paint.setTextSize(24); // 设置字体大小
        paint.setTextAlign(Paint.Align.CENTER); // 设置文字居中对齐
        paint.setAntiAlias(true); // 抗锯齿
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //onDraw()是Android视图绘制的核心方法，这里重写了它以便在SeekBar上绘制自定义内容。
        int max = getMax()-1; // 用getMax()方法获取SeekBar的最大值，显示从0 到 max-1的数字
        if (max < 1) return; // 避免除以零或负数

        // 计算SeekBar的实际可用宽度，考虑内边距和滑块偏移量
        int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();//实际宽度等于控件宽度-左边内边距-右边内边距
        float step = availableWidth / (float) (max + 1); // 每个步长的空间，包括最后一个数值的位置（实际上就是将SeekBar分成最大空间份，即步长为1）

        // 动态调整字体大小，确保文本清晰可见
        float textSize = Math.min(30, availableWidth / (max * 0.6f));
        //这个算式从一个固定值和一个动态计算的值中选择其中最小的值作为文本的大小。其中0.6f这个值增加的话就会减少文本间的距离，如果减小就会增加文本间的距离
        paint.setTextSize(textSize);//设置画笔的字体大小

        for (int i = 0; i <= max; i++) {//绘画从0-max的数字
            paint.setColor(Color.parseColor("#ffFFFFFF"));
            // 计算当前数值对应的位置，位于每一步长空间的中心
            float centerX = getPaddingLeft() + i * step + step / 2; // 确保数字居中于各自步长空间的中间
            //getPaddingLeft()方法获取SeekBar左边的内边距，确保数值不会与边界重叠。i * step：计算当前数值在其对应的步长位置。step / 2：将文本居中显示于该步长空间的中心位置。
            String text = String.valueOf(i);//显示数字
            paint.getTextBounds(text, 0, text.length(), rect);//这行代码用于获取当前数值字符串的边界框。rect对象包含了文本的高度和宽度信息，这对于后续正确地放置文本非常重要。

            // 绘制文本，y坐标需要根据字体的高度进行适当调整
            canvas.drawText(text, centerX, getHeight() / 2 + rect.height() / 2, paint);//这里的参数分别是内容、x坐标和纵坐标
            //getHeight() / 2 : 计算的是SeekBar的高度的一半，即纵坐标从一半的位置开始画。具体效果就是数字花在上半格。
            //rect.height() / 2 ： 计算的是text的高度的一半，加上这个值之后，text的中心点会与SeekBar的中心点重合，即让文本居中绘制

            // 在两个数值之间画竖线，除了第一个数字前和最后一个数字后
            if (i < max) {//i<max则不会绘制最后一个数字后面的竖线
                // 竖线位置位于两个数值之间的中点
                float lineX = getPaddingLeft() + (i + 1) * step;//将竖线画在一格空间的右侧，所以第一个数字的左侧不会有竖线
                paint.setColor(Color.parseColor("#888888")); // 设置颜色为灰色
                canvas.drawLine(lineX, getHeight() / 4, lineX, 3 * getHeight() / 4, paint);
            }
        }
    }

}
